package com.fendaren.controller;

import com.fendaren.api.mq.RabbitMQSMSConfig;
import com.fendaren.base.BaseInfoProperties;
import com.fendaren.grace.result.GraceJSONResult;
import com.fendaren.grace.result.ResponseStatusEnum;
import com.fendaren.pojo.bo.RegistLoginBO;
import com.fendaren.pojo.Users;
import com.fendaren.pojo.mq.SMSContentQO;
import com.fendaren.pojo.vo.UsersVO;
import com.fendaren.service.UsersService;
import com.fendaren.util.IPUtil;
import com.fendaren.util.JSONUtil;
import com.fendaren.util.JWTUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONObject;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;
import java.util.UUID;

@RestController
@RequestMapping("passport")
@Slf4j
public class PassportController extends BaseInfoProperties {

    @Autowired
    private UsersService usersService;
    @Autowired
    private JWTUtils jWTUtils;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @GetMapping("getSMSCode")
    public GraceJSONResult getSMSCode(String mobile, HttpServletRequest request) {
        if (StringUtils.isBlank(mobile)) {
            return GraceJSONResult.errorMsg("");
        }
        // 限制用户只能在60s以内获得一次验证码
        String userIp = IPUtil.getRequestIp(request);
        redis.setnx60s(MOBILE_SMSCODE + ":" + userIp, mobile);
        String code = (int) ((Math.random() * 9 + 1) * 100000) + "";
        SMSContentQO  smsContentQO = new SMSContentQO();
        smsContentQO.setMobile(mobile);
        smsContentQO.setContent(code);
        rabbitTemplate.setConfirmCallback(new RabbitTemplate.ConfirmCallback(){
            @Override
            public void confirm(CorrelationData correlationData, boolean ack, String cause) {

                if (ack) {
                    log.info("交换机成功接收到消息:{}",cause);
                } else {
                    log.info("交换机接收消息失败，失败原因：{}",cause);
                }
            }
        });
        rabbitTemplate.convertAndSend(RabbitMQSMSConfig.SMS_EXCHANGE,"fendaren.sms.send.login",new JSONUtil().toJSON(smsContentQO),new CorrelationData(UUID.randomUUID().toString()));
        redis.set(MOBILE_SMSCODE + ":" + mobile, code, 30 * 60);
        return GraceJSONResult.ok();
    }

    @PostMapping("login")
    public GraceJSONResult login(@Valid @RequestBody RegistLoginBO registLoginBO, HttpServletRequest request) {
        String mobile = registLoginBO.getMobile();
        String code = registLoginBO.getSmsCode();
        // 1.从redis中获得验证码进行校验判断是否匹配
        String redisCode = redis.get(MOBILE_SMSCODE + ":" + mobile);
        if (StringUtils.isBlank(redisCode) || !redisCode.equalsIgnoreCase(code)) {
            return GraceJSONResult.errorCustom(ResponseStatusEnum.SMS_CODE_ERROR);
        }

        // 2.根据mobile查询数据库，判断用户是否存在
        Users user = usersService.queryMobileIsExist(mobile);
        if (user==null) {
            // 如果查询的用户为空，则表示没有注册过，需要注册入库
            user = usersService.createUser(mobile);
        }

        // 3.保存用户token，分布式会话到redis中
//        String uToken = TOKEN_USER_PREFIX+SYMBOL_DOT+ UUID.randomUUID().toString();
//        redis.set(REDIS_USER_TOKEN+":"+user.getMobile(), uToken);
        String jwt = jWTUtils.createJWTWithPrefix(new JSONObject(user).toString(),1000L,TOKEN_USER_PREFIX);

        // 4.用户登录注册以后，删除redis中的短信验证码
        redis.del(MOBILE_SMSCODE + ":" + mobile);

        // 5.返回用户的信息给前端
        UsersVO usersVO = new UsersVO();
        BeanUtils.copyProperties(user, usersVO);
        usersVO.setUserToken(jwt);

        return GraceJSONResult.ok(usersVO);
    }

    @PostMapping("logout")
    public GraceJSONResult logout(@RequestParam String userId, HttpServletRequest request) {

        // 后端只需要清除用户的token信息即可
        redis.del(REDIS_USER_TOKEN + ":" + userId);

        return GraceJSONResult.ok();
    }
}
